package cn.seqdata.jdbc;

import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.LocalDateTime;
import org.joda.time.LocalTime;

import java.math.BigDecimal;
import java.sql.*;
import java.util.Objects;
import java.util.function.Function;

/**
 * @Author: jrxian
 * @Date: 2019/1/27 19:08
 */
public final class JdbcUtils {
	private JdbcUtils() {
	}

	public static Boolean getBoolean(ResultSet rs, String columnLabel) throws SQLException {
		return getNullableNumber(rs, columnLabel, x -> !BigDecimal.ZERO.equals(x));
	}

	public static Integer getInteger(ResultSet rs, String columnLabel) throws SQLException {
		return getNullableNumber(rs, columnLabel, BigDecimal::intValue);
	}

	public static Long getLong(ResultSet rs, String columnLabel) throws SQLException {
		return getNullableNumber(rs, columnLabel, BigDecimal::longValue);
	}

	public static float getFloat(ResultSet rs, String columnLabel) throws SQLException {
		return getNullableNumber(rs, columnLabel, BigDecimal::floatValue, Float.NaN);
	}

	public static double getDouble(ResultSet rs, String columnLabel) throws SQLException {
		return getNullableNumber(rs, columnLabel, BigDecimal::doubleValue, Double.NaN);
	}

	public static Float getFloatObject(ResultSet rs, String columnLabel) throws SQLException {
		return getNullableNumber(rs, columnLabel, BigDecimal::floatValue);
	}

	public static Double getDoubleObject(ResultSet rs, String columnLabel) throws SQLException {
		return getNullableNumber(rs, columnLabel, BigDecimal::doubleValue);
	}

	private static <T> T getNullableNumber(ResultSet rs, String columnLabel,
		Function<BigDecimal, T> function) throws SQLException {
		return getNullableNumber(rs, columnLabel, function, null);
	}

	private static <T> T getNullableNumber(ResultSet rs, String columnLabel,
		Function<BigDecimal, T> function, T defval) throws SQLException {
		BigDecimal val = rs.getBigDecimal(columnLabel);
		return Objects.nonNull(val) ? function.apply(val) : defval;
	}

	public static DateTime getDateTime(ResultSet rs, String columnLabel) throws SQLException {
		Timestamp val = rs.getTimestamp(columnLabel);
		return Objects.nonNull(val) ? JodaUtils.toDateTime(val) : null;
	}

	public static LocalDateTime getLocalDateTime(ResultSet rs, String columnLabel) throws SQLException {
		Timestamp val = rs.getTimestamp(columnLabel);
		return Objects.nonNull(val) ? JodaUtils.toLocalDateTime(val) : null;
	}

	public static LocalDate getLocalDate(ResultSet rs, String columnLabel) throws SQLException {
		Date val = rs.getDate(columnLabel);
		return Objects.nonNull(val) ? JodaUtils.toLocalDate(val) : null;
	}

	public static LocalTime getLocalTime(ResultSet rs, String columnLabel) throws SQLException {
		Time val = rs.getTime(columnLabel);
		return Objects.nonNull(val) ? JodaUtils.toLocalTime(val) : null;
	}
}
